--
-- Combat rogue rotation helper
--

if _G.Rotor.player_class ~= 'ROGUE' then return end

-------------------------------------------
-- Local references to globals for speed and lint's happiness
-------------------------------------------
local Rotor = _G.Rotor

local strsplit = _G.strsplit
local max = _G.max
local GetTime = _G.GetTime
local UnitCanAttack = _G.UnitCanAttack
local UnitIsDead = _G.UnitIsDead
local UnitExists = _G.UnitExists

-------------------------------------------
-- Constants
-------------------------------------------

--
-- Spell ids
--
local SS_ID     = 1752  -- sinister strike
local KS_ID     = 51690 -- killing spree
local AR_ID     = 13750 -- adrenaline rush
local BF_ID     = 13877 -- blade flurry
local SND_ID    = 5171  -- slice'n'dice
local BGG_ID    = 84745 -- bg green phase
local BGY_ID    = 84746 -- bg yellow phase
local BGR_ID    = 84747 -- bg red phase
local RUP_ID    = 1943  -- rupture
local RS_ID     = 84617 -- revealing strike
local EA_ID     = 8647  -- expose armor
local EVIS_ID   = 2098  -- Eviscerate
local TOT_ID    = 57934 -- tricks of the trade
local COS_ID    = 31224 -- cloack of shadows
local VANISH_ID = 1856  -- vanish
local SPRINT_ID = 2983  -- sprint
local RECUP_ID  = 73651 -- recuperate
local FEINT_ID  = 1966
local KICK_ID   = 1766
local STEALTH_ID    = 1784
local BS_ID     = 13877 -- blade storm
local AMBUSH_ID = 8676

-- spell names
local SS_NAME = Rotor.spell_name_cache[SS_ID]
local RS_NAME = Rotor.spell_name_cache[RS_ID]
local SND_NAME = Rotor.spell_name_cache[SND_ID]
local EVIS_NAME = Rotor.spell_name_cache[EVIS_ID]
local RECUP_NAME = Rotor.spell_name_cache[RECUP_ID]
local RUP_NAME = Rotor.spell_name_cache[RUP_ID]

-- The module
local Mod = Rotor:NewModule('Rogue')
----------------------------------------
local spellAndAuraDefs = {
    common = {
        spells = {
            snd =       {SND_ID, with_buff = true},
                        --{RUP_ID, with_debuff = true},
                        {SPRINT_ID, with_buff = true, icon_pos = 5, icon_type = 'reminder'},
                        {TOT_ID, with_buff = true, icon_pos = 3},
            vanish =    {VANISH_ID, with_buff = true, icon_pos = 9},
                        {COS_ID, with_buff = true, icon_pos = 10},
            kick =      {KICK_ID, icon_pos = 11},
                        {FEINT_ID, icon_pos = 8, with_buff = true},
        },
        auras = {
            stealth =   {STEALTH_ID, icon_pos = 1},
                        {RECUP_ID, icon_pos = 12},
        },
    },
    combat = {
        spec = 2,
        spells = {
            ar =    {AR_ID, icon_pos = 6, with_buff = true},
                    {KS_ID, icon_pos = 7, with_buff = true},
            rs =    {RS_ID, with_debuff = true}
        },
        auras = {
            {BGR_ID, icon_pos = 2},
            {BGY_ID, icon_pos = 2},
            {BGG_ID, icon_pos = 2},
            {BS_ID, icon_pos = 12},
        },
    },
}
----------------------------------------
local spells
local buffs
local debuffs
----------------------------------------
local now = 0
local gcd = 0
local cp_delta = 0
----------------------------------------
function Mod:Init(opts)
    Rotor:initBlIndicator(4)
    spells, buffs, debuffs = Rotor:RegisterSpellsAndAuras(spellAndAuraDefs)
    Rotor:setInterruptSpell(spells.kick)
    Rotor:showPowerDisplay('0')
    Rotor:showUpperText('0')
    return true
end
----------------------------------------
function Mod:Done()
    spells = nil
    buffs = nil
    debuffs = nil
end
----------------------------------------
function Mod:CombatStateChanged()
    cp_delta = 0
end
----------------------------------------
function Mod:TargetChanged()
    cp_delta = 0
end
----------------------------------------
function Mod:CastSent(spell)
    if spell == SS_NAME or spell == RS_NAME then
        cp_delta = 1
    elseif spell == SND_NAME or spell == EVIS_NAME or spell == RECUP_NAME or spell == RUP_NAME then
        cp_delta = -Rotor.combo_points
    end
end
----------------------------------------
function Mod:CastFinished(spell, succ)
    if succ and (
        spell == SS_NAME or
        spell == RS_NAME or
        spell == SND_NAME or
        spell == EVIS_NAME or
        spell == RECUP_NAME or
        spell == RUP_NAME)
    then
        cp_delta = 0
    end
end
----------------------------------------
local function CheckUnsent(spell, time_since_last_sent)
    return (spell.sentAt <= spell.doneAt) and (spell.doneAt + (time_since_last_sent or 0.5) < now)
end
----------------------------------------
local function CheckOffCdAndUnsent(spell, time_since_last_sent, wth)
    return (spell.cd - (wth or 0.4) <= gcd) and CheckUnsent(spell, time_since_last_sent)
end
----------------------------------------
function Mod:NextSkill(gcd_arg, cur_spell)
    gcd = gcd_arg
    now = GetTime()

	local cp = Rotor.combo_points + cp_delta

    if buffs.stealth.active or buffs.vanish.active then
        return AMBUSH_ID
    elseif ((cp > 0 and buffs.snd.time_left - gcd <= 2) or ((cp >= 4) and (buffs.snd.time_left - gcd <= 4))) and CheckUnsent(spells.snd, 1.5) then
        return SND_ID
    elseif (cp == 4 and debuffs.rs.time_left - gcd < 1) and CheckUnsent(spells.rs, 1.5) then
        return RS_ID
    elseif cp == 5 then
        return EVIS_ID
    else
        return SS_ID
    end
end
----------------------------------------
function Mod:HandleCommandLine(cmd)
    local cmd, args = strsplit(' ', (cmd or ''):lower(), 2)
    -- handle command line here
end
----------------------------------------
function Mod:Detect()
    return Rotor.spec == 2 -- combat only for now
end
